<template>
  <a-drawer v-model:open="visible" width="420" :closable="false" :body-style="{ padding: 0, overflow: 'hidden' }" @close="close">
    <template #title>
      <div class="fbc">
        <div class="title">导出列表</div>
        <a-button type="text" class="icon-only-btn" @click="close"><i class="iconfont icon-close-line"></i></a-button>
      </div>
    </template>
    <div :class="['drawer-body', currentTask && 'show-file-list']">
      <div class="task-list-box">
        <div class="task-list my-scrollbar">
          <div v-for="taskItem in taskList" :key="taskItem.exportId" class="task-item no-select">
            <i class="iconfont icon-folder-3-line"></i>
            <span class="ml-12 elliptical-1 task-name" :title="taskItem.taskName">
              {{ taskItem.taskName }}
            </span>
            <span class="mt-4 elliptical-1 task-address" :title="taskItem.exportName"> 我的数据集/{{ taskItem.exportName }} </span>
            <div class="state">
              <!-- 导出中 -->
              <span v-if="taskItem.state == 1" class="total">{{ taskItem.handleNumber }}/{{ taskItem.totalNumber }}</span>
              <!-- 有失败文件 -->
              <template v-else-if="taskItem.state == 2">
                <div v-if="taskItem.failNumber" class="error-text">{{ taskItem.failNumber }} 失败 ！</div>
                <i v-else class="iconfont icon-checkbox-circle-fill"></i>
              </template>
              <!-- 导出失败 -->
              <div v-else-if="taskItem.state == 4">
                <div class="error-text">导出失败 ！</div>
                <div>{{ taskItem.handleNumber }}/{{ taskItem.totalNumber }}</div>
              </div>
            </div>
            <div class="hover-close">
              <a-button
                v-if="taskItem.failNumber && taskItem.state == 2"
                type="text"
                size="small"
                :disabled="currentTask?.exportId === taskItem.exportId"
                @click="selectTask(taskItem)"
              >
                失败详情
              </a-button>
              <a-button type="text" size="small" class="icon-only-btn" @click="deleteTask([taskItem.exportId])">
                <i class="iconfont icon-close-line"></i>
              </a-button>
            </div>
            <!-- 进度条 -->
            <a-progress
              v-if="taskItem.state == 1 || taskItem.state == 4"
              :percent="(taskItem.handleNumber / taskItem.totalNumber) * 100"
              :status="taskItem.state == 1 ? 'active' : 'exception'"
              :show-info="false"
              trail-color="#F5F5F5"
            />
          </div>
        </div>
        <div class="clear-all" @click="deleteAllTask"><i class="iconfont icon-delete-bin-fill"></i>清空</div>
      </div>

      <div class="file-list-box">
        <div class="back">
          <a-button type="text" class="icon-only-btn" @click="currentTask = null"><i class="iconfont icon-arrow-left-line"></i></a-button>
          失败详情（{{ currentTask?.taskName }}）
        </div>
        <div class="file-list my-scrollbar">
          <div v-for="(file, index) in failFileList" :key="index" class="file-item no-select">
            <i class="mr-4 iconfont icon-file-warning-line"></i>
            <div class="elliptical-1 file-name" :title="file.fileName">
              {{ file.fileName }}
            </div>
          </div>
        </div>
        <div class="footer">
          <div class="number">失败 {{ currentTask?.failNumber }}/{{ currentTask?.handleNumber }}</div>
          <a-button class="icon-with-btn" @click="resetUploadTask">
            <i class="iconfont icon-restart-line"></i>
            重传
          </a-button>
        </div>
      </div>
    </div>
  </a-drawer>
</template>

<script lang="ts" setup>
  import { ref } from 'vue'
  import { onBeforeUnmount } from 'vue'

  import { dmpTaskApi } from '@/services/api'

  import { ExportTagInfo, FailFile } from '../types'

  /* 显隐------------------------------------------------------------------------------- */
  const visible = ref(false)

  const open = () => {
    visible.value = true
    getTaskList()
  }
  const close = () => {
    visible.value = false
  }
  /* 切换层级------------------------------------------------------------------------------- */

  /* 数据展示------------------------------------------------------------------------------- */
  const taskList = ref<ExportTagInfo[]>([])
  const currentTask = ref<ExportTagInfo | null>(null) //当前任务
  const failFileList = ref<FailFile[]>([])

  const getTaskList = async () => {
    const res = await dmpTaskApi.onlineExportList()
    taskList.value = res.data
  }

  const getFailFileList = async () => {
    const res = await dmpTaskApi.onlineExportTaskFailFile(currentTask.value?.exportId || '')()
    failFileList.value = res.data
  }

  const deleteTask = async (ids: string[]) => {
    await dmpTaskApi.onlineExportCancel({ exportIds: ids })
    await getTaskList()
    if (taskList.value.length === 0) {
      close()
    }
  }

  const deleteAllTask = () => {
    const ids = taskList.value.map(item => item.exportId)
    if (ids.length === 0) return
    deleteTask(ids)
  }

  const selectTask = (task: ExportTagInfo) => {
    currentTask.value = task
    getFailFileList()
  }

  // 重传任务
  const resetUploadTask = async () => {
    if (currentTask.value === null) return

    const { exportId } = currentTask.value
    currentTask.value = null

    dmpTaskApi
      .onlineExportTaskReset(exportId)({})
      .finally(() => {
        getTaskList()
      })
  }

  const timer = setInterval(() => {
    if (!visible.value) return
    getTaskList()
  }, 3000)

  onBeforeUnmount(() => {
    clearInterval(timer)
  })

  /* ------------------------------------------------------------------------------- */

  defineExpose({
    open,
    close
  })
</script>

<style lang="less" scoped>
  .drawer-body {
    display: flex;
    overflow: hidden;
    width: 840px;
    height: 100%;
    transition: transform 0.3s ease-in-out;

    &.show-file-list {
      transform: translateX(-420px);
    }

    .task-list-box {
      display: flex;
      padding: 24px 0;
      width: 420px;
      height: 100%;
      flex-direction: column;

      .task-list {
        position: relative;
        overflow-y: auto;
        padding: 0 24px;
        flex-grow: 1;

        .task-item {
          position: relative;
          display: flex;
          padding: 4px 8px;
          width: 100%;
          border-radius: 2px;
          align-content: flex-start;
          flex-wrap: wrap;

          .iconfont {
            height: 22px;
            font-size: 22px;
            color: @text03;
            line-height: 1;

            &.success {
              color: @success;
            }

            &.error {
              color: @danger;
            }

            &.loading {
              color: #1868e9;
              animation: rotate 2s linear infinite;
            }
          }

          .task-name {
            width: 190px;
            height: 22px;
            color: @text01;
            line-height: 22px;
          }

          .shortLine {
            width: 110px;
          }

          .task-address {
            width: 170px;
            height: 20px;
            line-height: 20px;
            color: @text03;
          }

          .state {
            position: absolute;
            top: 16px;
            right: 8px;
            display: flex;
            justify-content: flex-end;
            align-items: center;
            width: 100px;
            height: 20px;
            line-height: 20px;

            .total {
              transform: translateX(-10px);
            }

            .error-text {
              color: @danger;
            }

            .icon-checkbox-circle-fill {
              color: @success;
            }
          }

          .hover-close {
            position: absolute;
            top: 8px;
            right: 8px;
            display: none;
            justify-content: flex-end;
            align-items: center;

            .close-btn {
              width: 20px;
              height: 20px;
              background-color: rgba(0, 0, 0, 0.05);
              border-radius: 6px;

              .iconfont {
                cursor: pointer;
                color: @text02;
              }
            }
          }

          .ant-progress {
            margin-top: 4px;

            :deep(.ant-progress-inner) {
              height: 3px;
            }
          }

          &::after {
            position: absolute;
            bottom: -12px;
            left: 0;
            width: 100%;
            height: 1px;
            background-color: @border1;
            content: '';
          }

          & + .task-item {
            margin-top: 28px;
          }

          &:hover {
            background: rgba(0, 0, 0, 0.05);

            .state {
              display: none;
            }

            .hover-close {
              display: flex;
            }
          }
        }
      }

      .clear-all {
        padding-top: 4px;
        width: 100%;
        height: 26px;
        font-size: 14px;
        text-align: center;
        color: @text03;
        font-weight: 400;
        line-height: 22px;
        cursor: pointer;

        > i {
          display: inline-block;
          margin-right: 4px;
          transform: translateY(1px);
        }
      }
    }

    .file-list-box {
      display: flex;
      padding: 0;
      width: 420px;
      height: 100%;
      flex-direction: column;

      .back {
        display: flex;
        align-items: center;
        padding: 6px 20px;
        border-bottom: 1px solid #f5f5f5;
        background: #fff;
        .font14b();
      }

      .file-list {
        position: relative;
        overflow-y: auto;
        padding: 24px;
        width: 100%;
        flex-grow: 1;

        .file-item {
          position: relative;
          display: flex;
          align-items: center;
          color: @text01;
          .font14();

          .iconfont {
            font-size: 22px;
            color: @text04;
          }

          .file-name {
            width: 240px;
          }

          &::after {
            position: absolute;
            bottom: -12px;
            left: 0;
            width: 100%;
            height: 1px;
            background-color: @border1;
            content: '';
          }

          & + .file-item {
            margin-top: 28px;
          }
        }
      }

      .footer {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 4px 16px 6px;
        height: 48px;
        background: @background3;
        flex-shrink: 0;
        align-self: stretch;

        .number {
          color: @text02;

          .font12();
        }
      }
    }
  }
</style>
